<template>
  <div>
    <el-form class="search">
      <el-form-item label="用户查询">
        <el-input placeholder="请输入用户名称" style="width: 400px;" v-model="keyword"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" :disabled="!keyword" @click="search">查询</el-button>
        <el-button @click="clear">清空</el-button>
      </el-form-item>
    </el-form>
    <el-card>
      <el-button type="primary" @click="addUser">添加</el-button>
      <el-button type="danger" @click="delAllUser" :disabled="!selectIdArr.length">批量删除</el-button>
      <!-- 表格组件 -->
      <el-table style="margin: 13px 0;" border :data="userArr" @selection-change="selectChange">
        <el-table-column align="center" type="selection"></el-table-column>
        <el-table-column align="center" label="#" type="index" :index="formatIndex()"></el-table-column>
        <el-table-column align="center" label="ID" prop="id"></el-table-column>
        <el-table-column align="center" label="用户名字" prop="username"></el-table-column>
        <el-table-column align="center" label="用户名称" prop="name"></el-table-column>
        <el-table-column align="center" label="用户角色" prop="roleName"></el-table-column>
        <el-table-column align="center" label="创建时间" prop="createTime" show-overflow-tooltip></el-table-column>
        <el-table-column align="center" label="更新时间" prop="updateTime" show-overflow-tooltip></el-table-column>
        <el-table-column label="操作" width="300px" align="center">
          <template #="{ row }">
            <!-- row是用户对象的数据 -->
            <el-button icon="User" type="success" size="small" @click="setRole(row)">分配角色</el-button>
            <el-button icon="Edit" type="primary" size="small" @click="updateUser(row)">编辑</el-button>
            <el-popconfirm :title="`您确认要删除${row.username}吗？`" width="200" @confirm="delUser(row.id)">
              <template #reference>
                <el-button icon="Delete" type="danger" size="small">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页器组件 -->
      <el-pagination v-model:current-page="pageNo" v-model:page-size="pageSize" :page-sizes="[5, 10, 20, 40]" background
        layout="prev, pager, next, jumper,->,sizes,total" :total="total" @size-change="getUserInfo"
        @current-change="getUserInfo" />
      <!-- 添加或修改用户 抽屉组件 -->
      <el-drawer v-model="drawer">
        <template #header>
          <h4>{{ userParams.id ? '编辑用户' : '添加用户' }}</h4>
        </template>
        <template #default>
          <el-form :model="userParams" :rules="userRules" ref="userForm">
            <el-form-item label="用户姓名" prop="username">
              <el-input placeholder="请输入用户姓名" v-model="userParams.username"></el-input>
            </el-form-item>
            <el-form-item label="用户名称" prop="name">
              <el-input placeholder="请输入用户名称" v-model="userParams.name"></el-input>
            </el-form-item>
            <el-form-item label="用户密码" prop="password" v-if="!userParams.id">
              <el-input placeholder="请输入用户密码" v-model="userParams.password"></el-input>
            </el-form-item>
          </el-form>
        </template>
        <template #footer>
          <el-button type="primary" @click="save" size="large">确认</el-button>
          <el-button @click="cancel" size="large">取消</el-button>
        </template>
      </el-drawer>
      <!-- 分配角色抽屉组件 -->
      <el-drawer v-model="roleDrawer">
        <template #header>
          <h4>分配用户角色</h4>
        </template>
        <template #default>
          <el-form>
            <el-form-item label="用户名称">
              <el-input :disabled="true" v-model="userParams.username"></el-input>
            </el-form-item>
            <el-form-item label="职位列表">
              <!-- checkAll 是全选的复选框的值 -->
              <el-checkbox v-model="checkAll" :indeterminate="middle" @change="handleAllCheckedChange">全选</el-checkbox>
              <!-- 显示职位的复选框 -->
              <el-checkbox-group v-model="userRole" @change="handleCheckedChange">
                <!-- label是 el-checkbox-group 要收集的数据-->
                <el-checkbox v-for="( item ) in  allRole " :key="item.id" :label="item">{{ item.roleName
                }}</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
          </el-form>
        </template>
        <template #footer>
          <el-button type="primary" size="large" @click="confirm">确认</el-button>
          <el-button size="large" @click="roleDrawer = false">取消</el-button>
        </template>
      </el-drawer>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onBeforeMount, reactive, nextTick } from 'vue'
import { UserResponseData, Records, User, AllRoleResponseData, AllRole } from '@/api/user/user/type'
import { reqUserInfo, reqAddOrUpdateUser, reqAllRole, reqSetUserRole, reqDelUserAll, reqDelUser } from '@/api/user/user/index'
import { ElMessage } from 'element-plus';
// 当前页
const pageNo = ref<number>(1)
// 全部用户数据
const userArr = ref<Records>([])
// 收集用户信息
const userParams = reactive<User>({
  username: '',
  name: '',
  password: ''
})
// 用户表单实例
const userForm = ref()
// 当前页容量
const pageSize = ref<number>(5)
// 当前total
const total = ref<number>(0)
// 关键词
const keyword = ref<string>('')
// 搜索按钮回调
const search = () => {
  pageNo.value = 1,
    getUserInfo()
}
// 清空
const clear = () => {
  pageNo.value = 1,
    keyword.value = '',
    getUserInfo()
}
// 添加用户抽屉显示与隐藏
const drawer = ref<boolean>(false)
// 分配角色抽屉显示与隐藏
const roleDrawer = ref<boolean>(false)
// 收集是否全选的标识
const checkAll = ref<boolean>(false)
// 存放用户选择的已有职位
const userRole = ref<AllRole>([])
// 存放所有角色的数组
const allRole = ref<AllRole>([])
// 设置不确定态
const middle = ref<boolean>(true)
// 单选框的回调
const handleCheckedChange = (val: string[]) => {
  // 传入绑定的userRole的值，根据长度是否等于allRole的长度来设置中间态和全选框的值
  if (val.length === allRole.value.length) {
    middle.value = false
    checkAll.value = true
  } else {
    middle.value = true
    checkAll.value = false
  }
  console.log(userRole.value);

}
// 全选框状态的切换
const handleAllCheckedChange = (val: boolean) => {
  // 切换中间态
  middle.value = !val
  // 如果是true，把所有的复选框都勾上,如果是false，把所有的复选框都取消
  userRole.value = val ? allRole.value : []
}
// 分配角色的回调
const setRole = async (row: User) => {
  Object.assign(userParams, row) //合并数据
  // 获取全部职位和当前用户的职位
  const res: AllRoleResponseData = await reqAllRole(row.id as number)
  if (res.code === 200) {
    console.log(res);
    // 存储全部职位
    allRole.value = res.data.allRolesList
    // 存储用户的职位
    userRole.value = res.data.assignRoles
  }
  roleDrawer.value = true
}
// 确定按钮的回调
const confirm = async () => {
  // 收集数据
  const res = await reqSetUserRole({
    userId: userParams.id as number,
    // map修改原数组
    roleIdList: userRole.value.map((item) => item.id as number)
  })
  if (res.code == 200) {
    // 关闭抽屉
    roleDrawer.value = false
    ElMessage.success('分配角色成功')
    // 重新获取数据
    await getUserInfo()
  } else {
    ElMessage.error('分配角色失败')
  }
}
// 获取数据
const getUserInfo = async (pager = 1) => {
  pageNo.value = pager
  const res: UserResponseData = await reqUserInfo(pageNo.value, pageSize.value, keyword.value)
  if (res.code === 200) {
    userArr.value = res.data.records
    total.value = res.data.total
  }
}
// 格式化序号
const formatIndex = () => {
  return (pageNo.value - 1) * pageSize.value + 1
}
// 添加用户
const addUser = () => {
  // 抽屉显示出来
  drawer.value = true
  // 清空数据
  Object.assign(userParams, {
    username: '',
    name: '',
    password: ''
  })
  delete userParams.id
  // 清空错误信息
  nextTick(() => {
    userForm.value.clearValidate()
  })
}
// 更新用户
const updateUser = (row: User) => {
  // 抽屉显示出来
  drawer.value = true
  // 清空上一次的错误信息
  nextTick(() => {
    userForm.value.clearValidate()
  })
  // 替换数据
  Object.assign(userParams, row)
}
// 确定
const save = async () => {
  try {
    await userForm.value.validate()
    const res: any = await reqAddOrUpdateUser(userParams)
    console.log(res);
    if (res.code == 200) {
      ElMessage.success(userParams.id ? "更新成功" : "添加成功")
      drawer.value = false
      getUserInfo(userParams.id ? pageNo.value : 1)
      // 判断是否是修改，刷新页面
      if (userParams.id) {
        window.location.reload()
      }
    } else {
      ElMessage.error(res.data)
    }
  } catch (error) {
    console.log(error);
    ElMessage.error(userParams.id ? "更新失败" : "添加失败")
  }

}
// 取消按钮的回调
const cancel = () => {
  // 关闭抽屉
  drawer.value = false
  // 清空数据
  Object.assign(userParams, {
    username: '',
    name: '',
    password: ''
  })
  delete userParams.id
}
// 用户姓名校验
const validatorUsername = (_rule: any, value: any, callback: any) => {
  if (value.trim().length >= 5) {
    callback()
  } else {
    callback(new Error("用户名字不能小于5位"))
  }
}
// 用户名称校验
const validatorName = (_rule: any, value: any, callback: any) => {
  if (value.trim().length >= 6) {
    callback()
  } else {
    callback(new Error("用户名称不能小于6位"))
  }
}
// 用户密码校验
const validatorPassword = (_rule: any, value: any, callback: any) => {
  const reg = /^(?!.*\s)(?=.*[A-Z])(?=.*[a-z])(?=.*\d)[A-Za-z\d]{6,10}$/
  if (reg.test(value)) {
    callback()
  } else {
    callback(new Error("密码必须包含大写字母、小写字母、数字，且长度在6-10位之间"))
  }
}
// 用户表单校验
const userRules = {
  username: [{ required: true, trigger: 'blur', validator: validatorUsername }],
  name: [{ required: true, trigger: 'blur', validator: validatorName }],
  password: [{ required: true, trigger: 'blur', validator: validatorPassword }]
}
// 删除单个用户
const delUser = async (id: number) => {
  const res = await reqDelUser(id)
  if (res.code == 200) {
    ElMessage.success("删除成功")
    getUserInfo(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1)
  } else {
    ElMessage.error("删除失败")
  }
}
const selectIdArr = ref([])
// 删除多个用户
const delAllUser = async () => {
  const res = await reqDelUserAll(selectIdArr.value)
  if (res.code == 200) {
    ElMessage.success("删除成功")
    getUserInfo(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1)
  } else {
    ElMessage.error(res.data)
  }
}
// tabel复选框的回调
const selectChange = async (val: any) => {
  // 获取选中的id列表
  selectIdArr.value = val.map((item: any) => item.id)
}
onBeforeMount(() => {
  // 页面挂载发请求获取数据
  getUserInfo()
})
</script>

<style scoped lang="scss">
.search {
  display: flex;

  .el-form-item {
    margin-right: 40px;
  }
}
</style>
